import LocalAccess from "./local-access";
import * as fs from "fs";
import ContentNotExistException from "../api/exception/content-not-exist-exception";
import assert = require("assert");

export class LocalAccessImpl implements LocalAccess{

    private readonly filePath: string;

    constructor(filePath) {
        assert(filePath && filePath.trim() !== '')
        this.filePath = filePath;
    }

    async getContent(): Promise<Buffer> {
        return new Promise<Buffer>((resolve, reject) => {
            fs.readFile(this.filePath, (err, data) => {
                if (err){
                    reject(new ContentNotExistException(err.message));
                    return;
                }
                resolve(data);
            });
        });
    }

    async getLastModifiedTime(): Promise<Date> {
        return new Promise<Date>((resolve, reject)=>{
            fs.stat(this.filePath, function(err, stats) {
                if(err) {
                    reject(err);
                    return;
                }
                resolve(stats.mtime);
            });
        })
    }

    async update(content: Buffer): Promise<any> {
        await this.backupFileIfFileExist()
        return new Promise((resolve, reject)=>{
            fs.writeFile(this.filePath, content, (err) => {
                if (err) {
                    reject(err);
                    return;
                }
                resolve(this.filePath);
            });
        })
    }

    private async backupFileIfFileExist(){
        const fileCopyPath = this.filePath + '.synchronize.bak';
        const exist = await this.isFileExist(this.filePath);
        if(!exist) return Promise.resolve();
        return new Promise((resolve, reject)=>{
            fs.copyFile(this.filePath, fileCopyPath, (err) => {
                if (err) {
                    reject(err);
                    return;
                }
                resolve(fileCopyPath);
            });
        })
    }

    private async isFileExist(path): Promise<boolean>{
        return new Promise((resolve, reject) => {
            fs.stat(path, function(err, stats) {
                if(err){
                    resolve(false);
                    return;
                }
                resolve(true);
            });
        });
    }

}
